#include "hal_i2c.h"

int8_t hal_SW_iic_start(void)
{
    SDA_OUT();
    IIC1_WR_SCL = HIGH;
    IIC1_WR_SDA = HIGH;
    sys_delay_us(4);
    IIC1_WR_SDA = LOW;
    sys_delay_us(4);
    IIC1_WR_SCL = LOW;
    return RET_SUCCESS;
}

int8_t hal_SW_iic_stop(void)
{
    SDA_OUT();
    // IIC1_WR_SCL = HIGH;
    IIC1_WR_SDA = LOW;
    sys_delay_us(4);
    IIC1_WR_SDA = HIGH;
    sys_delay_us(4);
    IIC1_WR_SCL = HIGH;
    return RET_SUCCESS;
}

int8_t hal_SW_iic_waitack(void)
{
    uint8_t ucErrTime=0;
    SDA_IN();
    IIC1_WR_SDA = HIGH;
    sys_delay_us(1);
    IIC1_WR_SCL = HIGH;
    sys_delay_us(1);
    while(IIC1_RD_SDA)
    {
        sys_delay_us(1);
        if(ucErrTime>250)
        {
            hal_SW_iic_stop();
            DBG_ERR("wait ack time out\r\n");
            return RET_ERR;
        }
        ucErrTime++;
    }
    IIC1_WR_SCL = LOW;
    return RET_SUCCESS;
}

void hal_SW_iic_ack(void)
{
    IIC1_WR_SCL = LOW;
    SDA_OUT();
    IIC1_WR_SDA = LOW;
    sys_delay_us(2);
    IIC1_WR_SCL = HIGH;
    sys_delay_us(2);
    IIC1_WR_SCL = LOW;
}

void hal_SW_iic_nack(void)
{
    IIC1_WR_SCL = LOW;
    SDA_OUT();
    IIC1_WR_SDA = HIGH;
    sys_delay_us(2);
    IIC1_WR_SCL = HIGH;
    sys_delay_us(2);
    IIC1_WR_SCL = LOW;
}

void hal_SW_iic_wr_byte(uint8_t txd)
{
    uint8_t t;
    SDA_OUT();
    IIC1_WR_SCL = LOW;
    for(t=0;t<8;t++)
    {
        IIC1_WR_SDA = (txd&0x80)>>7;
        txd<<=1;
        sys_delay_us(2);
        IIC1_WR_SCL = HIGH;
        sys_delay_us(2); 
        IIC1_WR_SCL = LOW;
        sys_delay_us(2);
    }
}

uint8_t hal_SW_iic_rd_byte(bool ack)
{
    uint8_t i,receive = 0;
    SDA_IN();
    for(i=0;i<8;i++ )
    {
        IIC1_WR_SCL = LOW;
        sys_delay_us(2);
        IIC1_WR_SCL = HIGH;
        receive <<= 1;
        if(IIC1_RD_SDA)
        {
            receive++;
        }
        sys_delay_us(1); 
    }					 
    if (!ack)
    {
        hal_SW_iic_nack();
    }
    else
    {
        hal_SW_iic_ack();
    }
    return receive;
}

int8_t hal_SW_iic_init(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;
    I2C1_GPIO_PeriphClockFunc(I2C1_GPIO_PeriphClock, ENABLE);
    GPIO_InitStructure.GPIO_Pin = I2C1_GPIO_SCL | I2C1_GPIO_SDA;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//GPIO_OType_OD;//
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(I2C1_GPIO_PORT, &GPIO_InitStructure);
    IIC1_WR_SCL = HIGH;
    IIC1_WR_SDA = HIGH;
    return RET_SUCCESS;
}
